home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…ch: Other People's Memory / ADC Developer CD (1993-03) (''Other People's Memory'')_iso / Dev.CD Mar 93.iso / Technical Documentation / Sample Code / DTS.Lib & Samples / DTS.Lib / AEUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-22  |  8.5 KB  |  328 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:         DTS.Lib
  5. ** File:         AEUtils.c
  6. ** Written by:   Keith Rollin
  7. ** Modified by:  Eric Soldan
  8. **
  9. ** Copyright © 1990-1991 Apple Computer, Inc.
  10. ** All rights reserved.
  11. */
  12.  
  13.  
  14.  
  15. /*****************************************************************************/
  16.  
  17.  
  18.  
  19. #include "DTS.Lib2.h"
  20. #include "DTS.Lib.protos.h"
  21.  
  22. #ifndef __NOTIFICATION__
  23. #include <Notification.h>
  24. #endif
  25.  
  26. #ifndef __RESOURCES__
  27. #include <Resources.h>
  28. #endif
  29.  
  30. #include "Utilities.h"
  31.  
  32.  
  33.  
  34. /*****************************************************************************/
  35.  
  36.  
  37.  
  38. extern Boolean        gHasPPCToolbox;
  39.  
  40. static Boolean        gNotifyActive = false;
  41. static NMRec        gNotifyTheUser = {
  42.     nil,        /* qLink */
  43.     nmType,        /* qType */
  44.     0,            /* nmFlags */
  45.     0L,            /* nmPrivate */
  46.     0,            /* nmReserved */
  47.     1,            /* nmMark */
  48.     nil,        /* nmIcon */
  49.     (Handle)-1,    /* nmSound */
  50.     nil,        /* nmStr */
  51.     nil,        /* nmResp */
  52.     0L            /* nmRefCon */
  53. };
  54.  
  55.  
  56.  
  57. /*****************************************************************************/
  58. /*****************************************************************************/
  59.  
  60.  
  61.  
  62. /* Simply calls AEProcessAppleEvent and reports any errors.
  63. ** AEProcessAppleEvent looks in its table of registered events and sees if
  64. ** the current event is registered.  If so, off we go. */
  65.  
  66. #pragma segment AppleEvents
  67. void    DoHighLevelEvent(EventRecord *event)
  68. {
  69.     AEProcessAppleEvent(event);
  70. }
  71.  
  72.  
  73.  
  74. /*****************************************************************************/
  75.  
  76.  
  77.  
  78. /* This function returns the zone, machine, and application name for the
  79. ** indicated target descriptor. */
  80.  
  81. #pragma segment AppleEvents
  82. OSErr    GetTargetInfo(AEAddressDesc targetDesc, StringPtr zone,
  83.                       StringPtr machine, StringPtr application)
  84. {
  85.     ProcessSerialNumber targetPSN;
  86.     PortInfoRec            portInfo;
  87.     TargetID            theTargetID;
  88.     OSErr                err;
  89.  
  90.     zone[0]        = 0;
  91.     machine[0]     = 0;
  92.     application[0] = 0;
  93.     err = noErr;
  94.  
  95.     if (targetDesc.descriptorType == typeProcessSerialNumber) {
  96.         targetPSN = **(ProcessSerialNumber **)(targetDesc.dataHandle);
  97.         err = GetPortNameFromProcessSerialNumber(&portInfo.name, &targetPSN);
  98.         if (!err)
  99.             pcpy(application, portInfo.name.name);
  100.         return(err);
  101.     }
  102.  
  103.     if (targetDesc.descriptorType == typeTargetID) {
  104.         theTargetID = **(TargetID **)(targetDesc.dataHandle);
  105.         switch (theTargetID.location.locationKindSelector) {
  106.             case ppcNoLocation:
  107.                 break;
  108.             case ppcNBPLocation:
  109.                 pcpy(zone,    theTargetID.location.u.nbpEntity.zoneStr);
  110.                 pcpy(machine, theTargetID.location.u.nbpEntity.objStr);
  111.                 break;
  112.             case ppcNBPTypeLocation:
  113.                 break;
  114.         }
  115.         pcpy(application, theTargetID.name.name);
  116.         return(noErr);
  117.     }
  118.  
  119.     return(errAEWrongDataType);
  120. }
  121.  
  122.  
  123.  
  124. /*****************************************************************************/
  125.  
  126.  
  127.  
  128. /* Creates a TargetID.
  129. **
  130. ** If sendDirect is TRUE, the target is specified by setting a
  131. ** ProcessSerialNumber to kCurrentProcess.  This has the advantage of sending
  132. ** the message directly to ourselves, bypassing ePPC and gaining about a 10-15x
  133. ** speed improvement.  If sendDirect is FALSE, we see if we have the
  134. ** PPCToolBox.  If not, then we are forced to do a direct send.  If we do have
  135. ** the PPCToolbox, then we call PPCBrowser.  We then look at the reply, and
  136. ** factor in the mode we are going to use in AESend.  If that mode is
  137. ** kAEWaitReply and the user selected us as the target, we have to turn that
  138. ** into a direct send.  This is because the AppleEvent Manager will otherwise
  139. ** post the event as a high-level event.  However, we are busy waiting for a
  140. ** reply, not looking for events, so we'll hang.  We avoid this by forcing a
  141. ** direct send. */
  142.  
  143. #pragma segment AppleEvents
  144. OSErr    MakeTarget(AEAddressDesc *target, Boolean sendDirect, short replyMode,
  145.                    Str255 prompt, Str255 applListLabel,
  146.                    PPCFilterProcPtr portFilter,
  147.                    char *theLocNBPType)
  148. {
  149.     OSErr                    err;
  150.     ProcessSerialNumber     targetPSN;
  151.     ProcessSerialNumber     myPSN;
  152.     TargetID                theTargetID;
  153.     Boolean                    sendingToSelf;
  154.  
  155.     static LocationNameRec    location;
  156.     static PortInfoRec        portInfo;
  157.     static Boolean            defaultOK = false;
  158.  
  159.     err = noErr;    /* Make sure we do the code for the second main if. */
  160.  
  161.     target->dataHandle = nil;
  162.         /* Assume we will fail and nil this descriptor out. */
  163.  
  164.     if (!sendDirect) {
  165.         if (!gHasPPCToolbox)
  166.             sendDirect = true;    /* No tools to send with, so send direct. */
  167.  
  168.         else {        /* We are not sending to self. */
  169.                     /* sendDirect is false.           */
  170.             err = PPCBrowser(
  171.                 prompt,            /* Browse dialog box prompt.           */
  172.                 applListLabel,    /* The 'programs' list title.           */
  173.                 defaultOK,        /* Initially false.                       */
  174.                 &location,        /* Correct if defaultOK is true.       */
  175.                 &portInfo,        /* Correct if defaultOK is true.       */
  176.                 portFilter,        /* Port filtering.                       */
  177.                 (StringPtr)theLocNBPType    /* List ports of this type */
  178.             );
  179.  
  180.             if (!err) {                    /* If user didn't cancel... */
  181.                 defaultOK = true;        /* Default to the same port next time. */
  182.                 if (replyMode == kAEWaitReply) {
  183.                     /* Sender wants a reply and will be waiting... */
  184.  
  185.                     sendingToSelf = false;
  186.                         /* Assume that we aren't sending to ourselves. */
  187.  
  188.                     if (!location.locationKindSelector) {
  189.                         /* Hey, we are sending to ourselves! */
  190.  
  191.                         err = GetProcessSerialNumberFromPortName(
  192.                                 &portInfo.name, &targetPSN);
  193.                         if (!err) {
  194.                             GetCurrentProcess(&myPSN);
  195.                             err = SameProcess(&targetPSN, &myPSN, &sendingToSelf);
  196.                         }
  197.                     }
  198.  
  199.                     if (sendingToSelf)
  200.                         sendDirect = true;
  201.  
  202.                 }
  203.             }
  204.         }
  205.     }
  206.  
  207.     if (!err) {
  208.         if (sendDirect) {
  209.             /* Finally, we get to the point... */
  210.  
  211.             targetPSN.highLongOfPSN = 0;
  212.             targetPSN.lowLongOfPSN = kCurrentProcess;
  213.                 /* Process serial # is equal to kCurrentProcess.  This
  214.                 ** bypasses ePPC and speeds up things considerably. */
  215.  
  216.             err = AECreateDesc(
  217.                 typeProcessSerialNumber,    /* Standard PSN descriptor type. */
  218.                 (Ptr)&targetPSN,            /* "No ePPC" process serial #.     */
  219.                 sizeof(targetPSN),            /* Size of data (2 longs).         */
  220.                 target                        /* Wherefore art thou desc.         */
  221.             );
  222.         }
  223.         else {
  224.             theTargetID.location = location;
  225.             theTargetID.name     = portInfo.name;
  226.                 /* The fields sessionID does not need to be filled in now.
  227.                 ** The sessionID is returned when you actually connect to
  228.                 ** a port.  You can then use the sessionID from that point
  229.                 ** on to improve speed.
  230.                 **
  231.                 ** You also don't need to fill in the recvrName field at this
  232.                 ** point.  This is filled in, again, when the session is
  233.                 ** actually established.
  234.                 **
  235.                 ** The amount of data for a non-us target is bigger.
  236.                 ** We need the whole dealie for our target, since
  237.                 ** it is out on the net somewhere. */
  238.  
  239.             err = AECreateDesc(
  240.                 typeTargetID,            /* Standard target descriptor type. */
  241.                 (Ptr)&theTargetID,        /* The data for the descriptor.        */
  242.                 sizeof(theTargetID),    /* Size of the data.                */
  243.                 target                    /* Wherefore art thou desc.            */
  244.             );
  245.         }
  246.     }
  247.     return (err);
  248. }
  249.  
  250.  
  251.  
  252. /*****************************************************************************/
  253.  
  254.  
  255.  
  256. /* Used to check for any unread required parameters. Returns true if we
  257. ** missed at least one. */
  258.  
  259. #pragma segment AppleEvents
  260. Boolean    MissedAnyParameters(AppleEvent *message)
  261. {
  262.     OSErr        err;
  263.     DescType    ignoredActualType;
  264.     AEKeyword    missedKeyword;
  265.     Size        ignoredActualSize;
  266.     EventRecord    event;
  267.  
  268.     err = AEGetAttributePtr(    /* SEE IF PARAMETERS ARE ALL USED UP.          */
  269.         message,                /* AppleEvent to check.                          */
  270.         keyMissedKeywordAttr,    /* Look for unread parameters.                  */
  271.         typeWildCard,            /* So we can see what type we missed, if any. */
  272.         &ignoredActualType,        /* What it would have been if not coerced.      */
  273.         (Ptr)&missedKeyword,    /* Data area.  (Keyword not handled.)          */
  274.         sizeof(missedKeyword),    /* Size of data area.                          */
  275.         &ignoredActualSize        /* Actual data size.                          */
  276.     );
  277.  
  278. /* No error means that we found some unused parameters. */
  279.  
  280.     if (err == noErr) {
  281.         event.message = *(long *) &ignoredActualType;
  282.         event.where = *(Point *) &missedKeyword;
  283.         err = errAEEventNotHandled;
  284.     }
  285.  
  286. /* errAEDescNotFound means that there are no more parameters.  If we get
  287. ** an error code other than that, flag it. */
  288.  
  289.     return(err != errAEDescNotFound);
  290. }
  291.  
  292.  
  293.  
  294. /*****************************************************************************/
  295.  
  296.  
  297.  
  298. #pragma segment AppleEvents
  299. void    NotifyCancel(void)
  300. {
  301.     if (gNotifyActive) {
  302.         NMRemove((NMRecPtr)&gNotifyTheUser);
  303.         gNotifyActive = false;
  304.     }
  305. }
  306.  
  307.  
  308.  
  309.  
  310. /*****************************************************************************/
  311.  
  312.  
  313.  
  314. #pragma segment AppleEvents
  315. void    NotifyUser(void)
  316. {
  317.     if (gInBackground) {
  318.         if (!gNotifyActive) {
  319.             gNotifyTheUser.nmIcon = GetResource('SICN', 128);
  320.             NMInstall(&gNotifyTheUser);
  321.             gNotifyActive = true;
  322.         }
  323.     }
  324. }
  325.  
  326.  
  327.  
  328.